/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2003 Ferdinando Ametrano
 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
 Copyright (C) 2004, 2005 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/license.shtml>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

/*! \file OSRandomVariable.h
    \brief OSRandomVariable.h
*/

#ifndef _OSProbabilitySpace_
#define _OSProbabilitySpace_
#include <boost/operators.hpp>


    //! prototype function for ProbabilitySpace.
// We start from a set class for which Union (operator |) and Intersection (operator &) are defined
template<class Set>
class EventSet : public Set,
	private      
		boost::andable< particle<OS_double>          
    ,	boost::orable< particle<OS_double>     
      > > 
{
	typedef typename Set::value_type	value_type;
	typedef typename Set				Base;
	EventSet(const Base & from) : Base(from){};
};

// A sample Space is a set of Events for which the function in is defined
template <class Set>
class SampleSpace : public Eventset<Set>
{
public:
	typedef typename Eventset<Set>				Base;
	typedef typename ElementSet					container_type;
	typedef typename Base::value_type			value_type;
	inline OS_bool in(const & value_type point) = 0
};

template <class Set>
struct Probability : public std::unary_function<const typename Eventset<Set> &, OS_double>
{
public :
		typedef typename Eventset<Set>				EventSet_type;
		typedef typename SampleSpace<Set>			SampleSpace_type;
		inline OS_double operator()(const EventSet_type& B, const EventSet_type& A) const //conditional probability
		{	// apply operator+ to operands
			return (*this)(B&A)/(*this)(A);
		};
		const SampleSpace_type & SampleSpace() = 0;
		void axiom2() {
			OS_DYNAMIC_CHECK( (*this)(SampleSpace()) == 1. );
		}
};



#endif
